/*******************************************************************************
* Copyright 2015 Maximilian Stark | Dakror <mail@dakror.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package de.dakror.vloxlands;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.Json.ReadOnlySerializer;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.ScreenUtils;
import de.dakror.vloxlands.game.Game;
import de.dakror.vloxlands.game.entity.Entity;
import de.dakror.vloxlands.game.item.Item;
import de.dakror.vloxlands.game.voxel.Voxel;
import de.dakror.vloxlands.layer.DebugLayer;
import de.dakror.vloxlands.layer.Layer;
import de.dakror.vloxlands.layer.LoadingLayer;
import de.dakror.vloxlands.render.DDirectionalShadowLight;
import de.dakror.vloxlands.ui.skin.DoubleDrawable;
import de.dakror.vloxlands.ui.skin.TilesetDrawable;
import de.dakror.vloxlands.util.Compressor;
import de.dakror.vloxlands.util.InternalAssetManager;
import de.dakror.vloxlands.util.VxiLoader;
import de.dakror.vloxlands.util.base.GameBase;
import de.dakror.vloxlands.util.math.Bits;
import de.dakror.vloxlands.util.math.MathHelper;
public class Vloxlands extends GameBase {
public static ShapeRenderer shapeRenderer;
public static Vloxlands instance;
public static AssetManager assets;
public static Skin skin;
public static boolean showPathDebug;
public static boolean wireframe;
@Override
public void create() {
instance = this;
Gdx.app.setLogLevel(Application.LOG_DEBUG);
Config.init();
InternalAssetManager.init();
Entity.loadEntities();
Voxel.loadVoxels();
Voxel.buildMeshes();
Item.loadItems();
setFullscreen(Config.pref.getBoolean("fullscreen"));
assets = new AssetManager();
assets.setLoader(Model.class, ".vxi", new VxiLoader(assets, new InternalFileHandleResolver()));
skin = new Skin(new TextureAtlas(Gdx.files.internal("skin/RPGConstrUI/uiskin.atlas"))) {
@Override
protected Json getJsonLoader(FileHandle skinFile) {
Json json = super.getJsonLoader(skinFile);
json.setSerializer(TilesetDrawable.class, new ReadOnlySerializer<TilesetDrawable>() {
@SuppressWarnings("rawtypes")
@Override
public TilesetDrawable read(Json json, JsonValue jsonData, Class type) {
TextureRegion[] regions = new TextureRegion[9];
for (int i = 0; i < 9; i++) {
try {
regions[i] = getRegion(json.readValue(TilesetDrawable.values[i], String.class, jsonData));
} catch (Exception e) {}
}
TilesetDrawable td = new TilesetDrawable(regions);
if (jsonData.has("center") && json.readValue("center", Boolean.class, jsonData) == true) td.center = true;
return td;
}
});
json.setSerializer(DoubleDrawable.class, new ReadOnlySerializer<DoubleDrawable>() {
@SuppressWarnings("rawtypes")
@Override
public DoubleDrawable read(Json json, JsonValue jsonData, Class type) {
Drawable fg = null;
try {
if (jsonData.has("fg_tile") && json.readValue("fg_tile", Boolean.class, jsonData) == Boolean.TRUE) fg = getTiledDrawable(json.readValue("fg", String.class, jsonData));
else fg = getDrawable(json.readValue("fg", String.class, jsonData));
} catch (Exception e) {
e.printStackTrace();
}
Drawable bg = null;
try {
if (jsonData.has("bg_tile") && json.readValue("bg_tile", Boolean.class, jsonData) == Boolean.TRUE) bg = getTiledDrawable(json.readValue("bg", String.class, jsonData));
else bg = getDrawable(json.readValue("bg", String.class, jsonData));
} catch (Exception e) {
e.printStackTrace();
}
return new DoubleDrawable(fg, bg);
}
});
return json;
}
@Override
public Drawable getDrawable(String name) {
TilesetDrawable tilesetDrawable = optional(name, TilesetDrawable.class);
if (tilesetDrawable != null) return tilesetDrawable;
DoubleDrawable doubleDrawable = optional(name, DoubleDrawable.class);
if (doubleDrawable != null) return doubleDrawable;
return super.getDrawable(name);
}
};
skin.load(Gdx.files.internal("skin/RPGConstrUI/uiskin.json"));
getMultiplexer().addProcessor(0, new GestureDetector(this));
getMultiplexer().addProcessor(0, this);
Gdx.input.setInputProcessor(getMultiplexer());
new Updater();
addLayer(new LoadingLayer());
}
@Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
for (Layer l : layers)
l.render(Gdx.graphics.getDeltaTime());
}
@SuppressWarnings("deprecation")
@Override
public boolean keyUp(int keycode) {
if (keycode == Keys.F1) {
Config.debug = !Config.debug;
toggleLayer(new DebugLayer());
return true;
}
if (keycode == Keys.F2) showPathDebug = !showPathDebug;
if (keycode == Keys.F3) wireframe = !wireframe;
if (Game.world != null) {
if (keycode == Keys.F4) Game.world.setDataMap(Game.world.getDataMap() + 1);
if (keycode == Keys.F5) Game.world.setDataMap(Game.world.getDataMap() - 1);
if (keycode == Keys.F6) saveGame();
if (keycode == Keys.F7) Game.world.getIslands()[0].pos.y += 5;
if (keycode == Keys.F9) Config.shadowQuality++;
if (keycode == Keys.F10) Config.shadowQuality--;
if (keycode == Keys.F9 || keycode == Keys.F10) {
Config.shadowQuality = Math.max(0, Config.shadowQuality);
((DDirectionalShadowLight) Game.instance.env.shadowMap).setShadowQuality(Config.shadowQuality);
}
if (keycode == Keys.F11) {
setFullscreen(!Gdx.graphics.isFullscreen());
return true;
}
if (keycode == Keys.F12) {
takeScreenshot();
return true;
}
if (keycode == Keys.UP) Config.changeGameSpeed(true);
if (keycode == Keys.DOWN) Config.changeGameSpeed(false);
if (keycode == Keys.SPACE) Config.paused = !Config.paused;
}
return false;
}
@Override
public void pause() {
Config.savePrefs();
}
public void setFullscreen(boolean fullscreen) {
if (!fullscreen) Gdx.graphics.setDisplayMode(Gdx.graphics.getDesktopDisplayMode().width, Gdx.graphics.getDesktopDisplayMode().height, false);
else Gdx.graphics.setDisplayMode(Gdx.graphics.getDesktopDisplayMode().width, Gdx.graphics.getDesktopDisplayMode().height, true);
}
public void takeScreenshot() {
String name = new SimpleDateFormat("dd.MM.yy HH-mm-ss").format(new Date());
FileHandle file = Gdx.files.external(".dakror/Vloxlands/screenshots/" + name + ".png");
PixmapIO.writePNG(file, getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true));
Gdx.app.log("Vloxlands.takeScreenshot", "Screenshot saved as " + name + ".");
}
private static Pixmap getScreenshot(int x, int y, int w, int h, boolean yDown) {
final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h);
if (yDown) {
// Flip the pixmap upside down
ByteBuffer pixels = pixmap.getPixels();
int numBytes = w * h * 4;
byte[] lines = new byte[numBytes];
int numBytesPerLine = w * 4;
for (int i = 0; i < h; i++) {
pixels.position((h - i - 1) * numBytesPerLine);
pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
}
pixels.clear();
pixels.put(lines);
}
return pixmap;
}
public void saveGame() {
try {
boolean wasNull = false;
if (Config.savegameName == null) {
wasNull = true;
Config.savegameName = new SimpleDateFormat("dd.MM.yy HH-mm-ss").format(new Date());
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bits.putLong(baos, Game.seed);
Game.world.save(baos);
FileHandle file = Gdx.files.external(".dakror/Vloxlands/maps/" + Config.savegameName + ".map");
file.writeBytes(Compressor.compress(baos.toByteArray()), false);
Gdx.app.log("Vloxlands.saveGame", "Game saved" + (wasNull ? " as " + file.name() + " (" + MathHelper.formatBinarySize(file.length(), 0) + ")." : "."));
} catch (IOException e) {
e.printStackTrace();
}
}
}